package com.panfeng.xcloud.dao.base;

import com.panfeng.xcloud.common.core.page.PageRequest;
import com.panfeng.xcloud.common.core.page.PageResponse;
import com.panfeng.xcloud.dao.mapper.BaseMapper;
import org.springframework.beans.factory.annotation.Autowired;

import java.io.Serializable;
import java.util.List;

public abstract class MapperSupport<K extends Serializable, E extends Serializable, M extends BaseMapper<E>> implements IMapperSupport<K, E> {

    @Autowired
    protected M mapper;

    @Override
    public Integer deleteByPrimaryKey(K pk) {
        return mapper.deleteByPrimaryKey(pk);
    }

    @Override
    public Integer insert(E e) {
        return mapper.insert(e);
    }

    @Override
    public Integer insertSelective(E e) {
        return mapper.insertSelective(e);
    }

    @Override
    public Integer updateByPrimaryKey(E e) {
        return mapper.updateByPrimaryKey(e);
    }

    @Override
    public Integer updateByPrimaryKeySelective(E e) {
        return mapper.updateByPrimaryKeySelective(e);
    }

    @Override
    public E selectByPrimaryKey(K pk) {
        return mapper.selectByPrimaryKey(pk);
    }

    @Override
    public List<E> selectAll(E condition) {
        return mapper.selectAll(condition);
    }

    @Override
    public List<E> selectList(PageRequest condition) {
        return mapper.selectList(condition);
    }

    @Override
    public Long selectCount(PageRequest condition) {
        return mapper.selectCount(condition);
    }

    public <D extends Serializable, C extends PageRequest> PageResponse<D> selectPage(C condition, SelectCount<C> selectCount, SelectList<D, C> selectList) {
        PageResponse<D> pageResponseDTO = new PageResponse<>();
        long count = selectCount.select(condition);
        pageResponseDTO.setTotalCount((int) count);
        pageResponseDTO.measureTotalPage(pageResponseDTO.getTotalCount(),condition.getPageSize());
        if(count > condition.getOffset()) {
            List<D> items = selectList.select(condition);
            pageResponseDTO.setItems(items);
        }
        pageResponseDTO.setPageNumber(condition.getPageNumber());
        pageResponseDTO.setPageSize(condition.getPageSize());
        return pageResponseDTO;
    }

    @Override
    public PageResponse<E> selectPage(PageRequest condition) {
        return selectPage(condition, this::selectCount, this::selectList);
    }

    @FunctionalInterface
    public interface SelectCount<C extends PageRequest> {
        long select(C condition);
    }

    @FunctionalInterface
    public interface SelectList<E, C extends PageRequest> {
        List<E> select(C condition);
    }
}
